package com.dzl.util;

import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.SSLContext;
import java.io.FileInputStream;
import java.security.KeyStore;
import java.util.Map;

public class HttpRequest {
	
	/**
	 * @tutorial 支持http,https
	 * @param url $url 要访问的站点
	 * @param data 只能是key/value的参数集合
	 * @param timeout 超时时间,单位秒
	 * @return 站点数据或失败信息
	 */
//	static public Object get(String url, Object data, int timeout) {
//		//将data转化为url参数:par1=val1&par2=va2&par3=val3
//		String param = "";
//		if(data != null && !data.equals("") && data instanceof Map) {
//			@SuppressWarnings("unchecked")
//			Map<String, Object> map = (Map<String, Object>)data;
//			for(Map.Entry<String, Object> entry : map.entrySet()) {
//				String key = entry.getKey() != null ? entry.getKey().toString() : "";
//				String val = entry.getValue() != null ? entry.getValue().toString() : "";
//				if(key.equals(""))
//					continue;
//				param += key + "=" + val + "&";
//			}
//		}
//		if(data != null && !data.equals("") && data instanceof JSONObject) {
//			JSONObject map = (JSONObject)data;
//			for(Object key : map.keySet()) {
//				if(key == null || key.equals(""))
//					continue;
//				String val = map.optString(key.toString());
//				if(val == null)
//					continue;
//				param += key + "=" + val + "&";
//			}
//		}
//		if(param.endsWith("&"))
//			param = param.substring(0, param.length() - 1);
//		if(!param.equals(""))
//			url += ((url.indexOf("?") != -1) ? "&" : "?") + param;
//
//		String result = "";
//
//		//创建http请求(post方式)
//		HttpGet httpGet = new HttpGet(url);
//		httpGet.addHeader("Content-Type", "text/html; charset=UTF-8");
//		//得指明使用UTF-8编码,否则到API服务器XML的中文不能被成功识别
//		//StringEntity stringEntity = new StringEntity(data.toString(), "UTF-8");
//		//httpGet.setEntity(stringEntity);
//
//		//设置请求器配置:如超时限制等
//		if(timeout>0) {
//			RequestConfig config = RequestConfig.custom().setSocketTimeout(timeout * 1000).setConnectTimeout(timeout * 1000).build();
//			httpGet.setConfig(config);
//		}
//
//		//提交post访问请求并获得返回值
//		//System.out.println("request: " + httpPost.getRequestLine());
//		try {
//			CloseableHttpClient httpClient = HttpClients.createDefault();
//			CloseableHttpResponse response = httpClient.execute(httpGet); //throw
//			HttpEntity httpEntity = response.getEntity();
//			//System.out.println("response status: " + response.getStatusLine());
//			result = EntityUtils.toString(httpEntity, "UTF-8"); //throw
//			//System.out.println("result: " + result);
//			try {
//				response.close(); //throw
//			}
//			catch(Exception e) {
//				e.printStackTrace();
//			}
//			httpClient.close(); //throw
//		}
//		catch(Exception e) {
//			e.printStackTrace();
//		}
//		//httpGet.abort();
//		return result;
//	}
 
	/**
	 * @tutorial 支持http,https
	 * @param  url 要访问的站点
	 * @param  data post可以是任意类型的数据,例如string,array,object,json等
	 * @param timeout 超时时间,单位秒
	 * @return 站点数据或失败信息
	 */
	static public Object post(String url, Object data, int timeout) {
		String result = "";
 
		//创建http请求(post方式)
		HttpPost httpPost = new HttpPost(url);
		httpPost.addHeader("Content-Type", "text/html; charset=UTF-8");
		//得指明使用UTF-8编码,否则到API服务器XML的中文不能被成功识别
		if(data != null && data instanceof String) { //支持上传字符串,如text,xml,json
			StringEntity stringEntity = new StringEntity(data.toString(), "UTF-8");
			httpPost.setEntity(stringEntity);
		}
		else if(data != null && data instanceof byte[]) { //支持上传原始数据,如文件
			ByteArrayEntity byteArrayEntity = new ByteArrayEntity((byte[])data);
			httpPost.setEntity(byteArrayEntity);
		}
 
		//设置请求器配置:如超时限制等
		if(timeout>0) {
			RequestConfig config = RequestConfig.custom().setSocketTimeout(timeout * 1000).setConnectTimeout(timeout * 1000).build();
			httpPost.setConfig(config);
		}
 
		//提交post访问请求并获得返回值
		//System.out.println("request: " + httpPost.getRequestLine());
		try {
			CloseableHttpClient httpClient = HttpClients.createDefault();
			CloseableHttpResponse response = httpClient.execute(httpPost); //throw
			HttpEntity httpEntity = response.getEntity();
			//System.out.println("response status: " + response.getStatusLine());
			result = EntityUtils.toString(httpEntity, "UTF-8"); //throw
			//System.out.println("result: " + result);
			try {	
				response.close(); //throw
			}
			catch(Exception e) {
				e.printStackTrace();
			}
			httpClient.close(); //throw
		}
		catch(Exception e) {
			e.printStackTrace();
		}	
		//httpPost.abort();
		return result;
	}
	
	//携带证书post
    public static String doCertificatePost(String mchId, String url, Object data,String filepath) throws Exception{

        //小程序退款需要调用双向证书的认证
        CloseableHttpClient httpClient = readCertificate(mchId,filepath);
        try {
            HttpPost httpost = new HttpPost(url); // 设置响应头信息
            httpost.addHeader("Connection", "keep-alive");
            httpost.addHeader("Accept", "*/*");
            httpost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
            httpost.addHeader("Host", "api.mch.weixin.qq.com");
            httpost.addHeader("X-Requested-With", "XMLHttpRequest");
            httpost.addHeader("Cache-Control", "max-age=0");
            httpost.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");

            //得指明使用UTF-8编码,否则到API服务器XML的中文不能被成功识别
    		if(data != null && data instanceof String) { //支持上传字符串,如text,xml,json
    			StringEntity stringEntity = new StringEntity(data.toString(), "UTF-8");
    			httpost.setEntity(stringEntity);
    		}
    		else if(data != null && data instanceof byte[]) { //支持上传原始数据,如文件
    			ByteArrayEntity byteArrayEntity = new ByteArrayEntity((byte[])data);
    			httpost.setEntity(byteArrayEntity);
    		}
    		
            CloseableHttpResponse response = httpClient.execute(httpost);
            try {
                HttpEntity entity = response.getEntity();
                String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8");
                EntityUtils.consume(entity);
                return jsonStr;
            } finally {
                response.close();
            }
        } catch (Exception e){
            throw new RuntimeException(e);
        } finally {
            httpClient.close();
        }
    }
    
  //微信小程序读取双向证书
    private static CloseableHttpClient readCertificate(String mchId,String filepath) throws Exception{
        /**
         * 注意PKCS12证书 是从微信商户平台-》账户设置-》 API安全 中下载的
         */
        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        //P12文件目录 证书路径，这里需要你自己修改，linux下还是windows下的根路径
        FileInputStream instream = new FileInputStream(filepath);
        try {
            keyStore.load(instream, mchId.toCharArray());//这里写密码..默认是你的MCHID
        } finally {
            instream.close();
        }
        // Trust own CA and all self-signed certs
        SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, mchId.toCharArray()).build();//这里也是写密码的
        // Allow TLSv1 protocol only
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext,SSLConnectionSocketFactory.getDefaultHostnameVerifier());
        return HttpClients.custom().setSSLSocketFactory(sslsf).build();
    }
 
}
